package com.heima.seckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.seckill.exception.GlobalException;
import com.heima.seckill.mapper.OrderMapper;
import com.heima.seckill.pojo.Order;
import com.heima.seckill.pojo.SeckillGoods;
import com.heima.seckill.pojo.SeckillOrder;
import com.heima.seckill.pojo.User;
import com.heima.seckill.service.IGoodsService;
import com.heima.seckill.service.IOrderService;
import com.heima.seckill.service.ISeckillGoodsService;
import com.heima.seckill.service.ISeckillOrderService;
import com.heima.seckill.utils.MD5Util;
import com.heima.seckill.utils.UUIDUtil;
import com.heima.seckill.vo.GoodsVo;
import com.heima.seckill.vo.OrderDetailVo;
import com.heima.seckill.vo.RespBeanEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author zhujia
 * @since 2022-04-20
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper,Order> implements IOrderService {
    @Autowired
    private ISeckillGoodsService seckillGoodsService;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    ISeckillOrderService seckillOrderService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 秒杀
     * @param user
     * @param goods
     * @return
     */
    @Transactional
    @Override
    public Order seckill(User user, GoodsVo goods) {
        // 1. 秒杀商品减库存
        SeckillGoods seckillGoods = seckillGoodsService.getOne(new QueryWrapper<SeckillGoods>().eq("goods_id", goods.getId()));
        seckillGoods.setStockCount(seckillGoods.getStockCount()-1);
//        seckillGoodsService.updateById(seckillGoods);
        boolean update = seckillGoodsService.update(new UpdateWrapper<SeckillGoods>().setSql("stock_count="+
                "stock_count-1").eq("id", seckillGoods.getId()).gt("stock_count", 0));
        if (seckillGoods.getStockCount()<1){
            redisTemplate.opsForValue().set("isStockEmpty:"+seckillGoods.getGoodsId(),0L);
            return null;
        }

        //2. 生成订单
        Order order = new Order();
        order . setUserId(user . getId());
        order. setGoodsId(goods. getId());
        order . setDeliveryAddrId(0L);
        order . setGoodsName (goods . getGoodsName());
        order . setGoodsCount(1);
        order . setGoodsPrice(seckillGoods. getSeckillPrice());
        order. setOrderChannel(1) ;
        order. setStatus(0);
        order . setCreateDate (new Date());
        orderMapper.insert(order);
        // 3. 生成秒杀订单
        SeckillOrder seckillOrder = new SeckillOrder();
        seckillOrder . setUserId(user . getId());
        seckillOrder . setOrderId(order. getId());
        seckillOrder . setGoodsId(goods. getId());
        seckillOrderService.save (seckillOrder) ;

        redisTemplate.opsForValue().set("order:"+user.getId()+":"+goods.getId(),seckillOrder);
        return order;
    }

    /**
     *
     *  订单详情
     * @param orderId
     * @return
     */
    @Override
    public OrderDetailVo detail(Long orderId) {
        if (orderId == null) {
            throw new GlobalException(RespBeanEnum.ORDER_NOT_EXIST);
        }
        Order order = orderMapper. selectById(orderId);
        GoodsVo goodsVo =  goodsService .findGoodsVoById(""+order.getGoodsId());
        OrderDetailVo detail = new OrderDetailVo(order,goodsVo);
        System.out.println(detail);
        return detail;
    }

    @Override
    public String createPath(User user, Long goodsId) {
        String str = MD5Util.md5( UUIDUtil.uuid() + "123456");
        redisTemplate.opsForValue().set("seckillPath:"+user.getId()+":"+goodsId, str,60, TimeUnit.SECONDS) ;
        return str;
    }
    /**
     * 判断秒杀地址是否正确
     * @param user
     * @param goodsId
     * @return
     */
    @Override
    public boolean checkPath(User user, String goodsId,String path) {
        if (user == null |Integer.parseInt(goodsId)<0 | StringUtils. isEmpty(path)) {
            return false;
        }
        String redisPath = (String) redisTemplate.opsForValue().get("seckillPath:" + user.getId() + ":" + goodsId);
        return path. equals(redisPath);
        }

    /**
     * 校验验证码
     * @param user
     * @param goodsId
     * @param captcha
     * @return
     */
    @Override
    public boolean checkCaptcha(User user, Long goodsId, String captcha) {
        if (StringUtils . isEmpty(captcha) |user == null| goodsId < 0) {
            return false;
        }
        String redisCaptcha = (String) redisTemplate.opsForValue().get("captcha:" + user . getId() + ":" + goodsId);
        return captcha.equals(redisCaptcha);
        }
}
